package com.my12306.user.controller;


import com.my12306.common.constant.CommonConstants;
import com.my12306.common.enums.CodeEnum;
import com.my12306.common.model.vo.PageVo;
import com.my12306.common.util.CommentUtils;
import com.my12306.common.util.PageUtils;
import com.my12306.common.util.RedisUtils;
import com.my12306.common.util.response.ResponseData;
import com.my12306.third.service.impl.SmsServiceImpl;
import com.my12306.user.model.LoginToken;
import com.my12306.user.model.po.PUserEntity;
import com.my12306.user.model.vo.UserVo;
import com.my12306.user.service.PUserService;
import com.my12306.user.service.auth.UserRoleService;
import com.my12306.user.util.auth.OauthUtils;
import com.my12306.user.util.auth.UserConstant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.provider.token.ConsumerTokenServices;
import org.springframework.util.Base64Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.my12306.common.util.CommentUtils.getPoToVo;

/**
 * 用户表
 *
 * @Author:苏牧夕
 * @Date:2020-05-15 17:36:13
 * @Version 1.0
 */
@RestController
@RequestMapping("user/puser")
@Api(value = "用户接口", tags = "用户接口")
public class PUserController {
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    private PUserService pUserService;
    @Autowired
    private OauthUtils oauthUtils;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private CommentUtils commentUtils;
    @Autowired
    private ConsumerTokenServices consumerTokenServices;

    /**
     * 列表
     */
    @GetMapping("/iextisn/{um}")
    @ApiOperation(value = "查询用户是否已经存在", httpMethod = "GET", response = ResponseData.class)
    public ResponseData isUserName(@ApiParam(name = "username", value = "用户注册名称") @PathVariable("um") String username, HttpServletResponse response) {
        System.out.println("=============> 判断是否存在用户名");
        PUserEntity pUserEntity = pUserService.queryUserByUsername(username);
        String uuid = UUID.randomUUID().toString();
        Cookie cookie = commentUtils.createCookie(CommonConstants.sms_cokkieName, uuid, "/", 3600);
        response.addCookie(cookie);
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        redisUtils.set(CommonConstants.smscode_key + uuid, 0, 1, TimeUnit.DAYS);
        if (pUserEntity != null) {
            return ResponseData.fail(CodeEnum.FAIL.getCode(), "用户名已经存在！");
        }
        return ResponseData.ok("用户名可用！");
    }

    //检查手机号是否已经存在
    @GetMapping("/isMobile/{mobile}")
    public ResponseData isMobile(@PathVariable("mobile")String mobile){

        boolean  isPhome = pUserService.isMobile(mobile);
        if (isPhome) {
            return ResponseData.ok();
        }
        return ResponseData.fail(CodeEnum.FAIL.getCode(),"手机号已经存在！");
    }
    @PostMapping("/rgtusr")
    @ApiOperation(value = "用户注册", httpMethod = "GET", response = ResponseData.class)
    public ResponseData register(@ApiParam(name = "pUserEntity", value = "用户注册") @Valid @RequestBody PUserEntity pUserEntity, HttpServletResponse response) throws Exception {
        String uuid = pUserEntity.getUuid();
        Object o = null;
        if (uuid != null) {
            o = redisUtils.get(SmsServiceImpl.rgscode + pUserEntity.getPhone() + "_" + uuid);
        } else {
            o = redisUtils.get(SmsServiceImpl.rgscode + pUserEntity.getPhone());
        }
        String orcode = "";
        if (o != null) {
            orcode = o.toString();
        }
        String captcha = pUserEntity.getCaptcha();
        if (!orcode.equals(captcha)) {
            return ResponseData.fail(CodeEnum.FAIL.getCode(), "验证码不正确！");
        }
        pUserEntity.setPassword(CommentUtils.decryptRSA(pUserEntity.getPassword()));
        Long aLong = pUserService.registerUser(pUserEntity);
        if (aLong != null) {
            return ResponseData.ok("注册成功！");

        }
        return ResponseData.fail(CodeEnum.FAIL.getCode(), "注册失败！");
    }

    /**
     * 列表
     */
    @PostMapping("/list")
    @ApiOperation(value = "查询用户列表", httpMethod = "GET", response = ResponseData.class)
    public ResponseData list(@ApiParam(name = "pageVo", value = "分页查询参数", required = false) @RequestBody PageVo pageVo) {

        PageUtils page = pUserService.queryUserListPage(pageVo);
        page.setTotalCount(page.getList().size());
        return ResponseData.ok().put("page", page);
    }


    @GetMapping("/logout")
    public ResponseData logout(HttpServletRequest request) {
        String authorization = request.getHeader("Authorization");
        return ResponseData.ok();
    }

    /**
     * 验证码
     */
    @GetMapping("/captcha.jpg")
    public void captcha(HttpServletResponse response, String uuid) throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //获取图片验证码

        BufferedImage image = pUserService.getCaptcha(uuid);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        IOUtils.closeQuietly(out);
    }

    /**
     * 登录
     */
    @PostMapping("/login")
    public ResponseData login(HttpServletRequest request, @RequestBody PUserEntity form) throws IOException {
        String uuid = form.getUuid();
        String captcha = form.getCaptcha();
        if (uuid == null || captcha == null) {
            return ResponseData.fail(CodeEnum.VALID_Exception.getCode(), "验证码不能为空!");
        }
        String key = RedisUtils.getKeyPrefix(UserConstant.Prefix, "user_", uuid);
        String code = (String) redisUtils.get(key);
        boolean equals = false;
        if (!StringUtils.isEmpty(code)) {
            equals = code.equals(captcha);
        }
        if (!equals) {
            return ResponseData.fail(CodeEnum.VALID_Exception.getCode(), "验证码错误!");
        }
        try {
            form.setPassword(CommentUtils.decryptRSA(form.getPassword()));
        } catch (Exception e) {
            return ResponseData.fail();
        }
        String url = "http://localhost:8003/my12306";
//        //请求提交的数据
        String client_id = "webapp";
        String client_secret = "secret";
        //1.申请令牌
        url = url + "/oauth/token";
        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        body.add("grant_type", "password");
        body.add("username", form.getUsername());
        body.add("password", form.getPassword());
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.add("Authorization", this.getHttpBasic(client_id, client_secret));
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);

        restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
                if (response.getRawStatusCode() != 400 && response.getRawStatusCode() != 401) {
                    super.handleError(response);
                }
            }
        });
        ResponseEntity<Map> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class);
        Map body1 = responseEntity.getBody();
        String access_token = (String) body1.get("access_token");
        if (!StringUtils.isEmpty(access_token)) {
            return ResponseData.ok().put("data", body1);
        } else {
            return ResponseData.fail(201, "密码错误|或者验证码错误");

        }
    }

    private String getHttpBasic(String clientId, String clientSecret) {
        String value = clientId + ":" + clientSecret;
        byte[] encode = Base64Utils.encode(value.getBytes());
        return "Basic " + new String(encode);
    }

    @PostMapping("/refresh_token")
    public ResponseData refresh_token(HttpServletRequest request, @RequestBody LoginToken token) throws IOException {

        String url = "http://localhost:8003/ilife";
//        //请求提交的数据
        String client_id = "webapp";
        String client_secret = "secret";
        //1.申请令牌
        url = url + "/oauth/token";
        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        body.add("grant_type", "refresh_token");
        body.add("refresh_token", token.getRefreshToken());
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.add("Authorization", this.getHttpBasic(client_id, client_secret));
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);

        restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
                if (response.getRawStatusCode() != 400 && response.getRawStatusCode() != 401) {
                    super.handleError(response);
                }
            }
        });
        ResponseEntity<Map> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class);
        Map body1 = responseEntity.getBody();

        String access_token = (String) body1.get("access_token");
        if (!StringUtils.isEmpty(access_token)) {
            return ResponseData.ok().put("data", body1);
        } else {
            return ResponseData.fail(201, "登陆失效，请重新登陆！");

        }
    }

    /**
     * 信息
     */
    @GetMapping("/info/{id}")
    //@RequiresPermissions("article:puser:info")
    public ResponseData info(@PathVariable("id") Long id) {
        PUserEntity pUser = pUserService.getById(id);
        UserVo userVo = new UserVo();
        getPoToVo(pUser, userVo);
        if (userVo != null) {
            List<Long> roleIds = userRoleService.selectRoleIdByUserId(id);
            userVo.setRoleIdList(roleIds);
            return ResponseData.ok().put("user", userVo);
        }
        return ResponseData.ok();
    }

    /**
     * 查询用户信息
     */
    @GetMapping("/info")
    //@RequiresPermissions("article:puser:info")
    public ResponseData userInfo(@PathVariable(value = "id", required = false) Long id) {
        PUserEntity pUser = null;
        if (id != null) {
            pUser = pUserService.getById(id);
        } else {
            String userInfo = oauthUtils.getUserInfo();
            pUser = pUserService.getUserInfoByUsername(userInfo);
        }
        return ResponseData.ok().put("user", pUser);
    }

    /**
     * 保存
     */
    @PostMapping("/save")
    @PreAuthorize("hasAnyAuthority('sys:user:save','user:post')")
    public ResponseData save(@RequestBody UserVo userVo) {
        ResponseData responseData = pUserService.saveUserVo(userVo);
        return responseData;
    }

    /**
     * 修改
     */
    @PutMapping("/update")
    @PreAuthorize("hasAnyAuthority('sys:user:update','user:put')")
    public ResponseData update(@RequestBody PUserEntity pUser) {

        Boolean aBoolean = pUserService.updateUserById(pUser);
        return ResponseData.ok();
    }

    /**
     * 修改密码
     */
    @PutMapping("/password")
    @PreAuthorize("hasAnyAuthority('sys:user:update','user:put')")
    public ResponseData updatePassword(@RequestBody UserVo userVo) {
        Boolean isSuccess = pUserService.updateUserPasswordById(userVo);
        if (isSuccess) {
            return ResponseData.ok();
        } else {
            return ResponseData.fail(CodeEnum.UPDATE_FAIL.getCode(), CodeEnum.UPDATE_FAIL.getMessage());
        }
    }

    /**
     * 删除
     */
    @DeleteMapping("/delete")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    public ResponseData delete(@RequestBody Long[] ids) {
        return pUserService.deleteBatchByUserIds(Arrays.asList(ids));
    }

}
